﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Globalization;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace blackhouse.Aparts.Web.Modules {
    public class ServiceForDays : Control {

        #region Fields

        private bool loadRaised;

        private Table table;
        private CheckBox refCheckbox;

        private List<TextBox> refBoxes = new List<TextBox>();

        #endregion

        #region Properties

        public DateTime FromDate { get; set; }
        public DateTime ToDate { get; set; }

        [Browsable(true)]
        [DefaultValue(ServiceDayVariant.Checkbox)]
        public ServiceDayVariant SelectDayVariant { get; set; }

        #endregion

        #region EventHandlers

        protected override void CreateChildControls() {
            base.CreateChildControls();

            this.table = new Table();
            this.table.CellPadding = 0;
            this.table.CellSpacing = 0;
            this.table.CssClass = "checkin-dates";
            this.Controls.Add(this.table);
        }

        protected override void OnLoad(EventArgs e) {
            base.OnLoad(e);

            if ((FromDate == DateTime.MinValue || ToDate == DateTime.MaxValue)
                || FromDate >= ToDate) return;

            this.RaiseLoad();
        }

        #endregion

        #region Methods

        public void RaiseLoad() {
            if (loadRaised) return;
            this.loadRaised = true;
            this.EnsureChildControls();
            TableRow headerRow = new TableRow();
            headerRow.TableSection = TableRowSection.TableHeader;
            this.table.Rows.Add(headerRow);
            this.BuildTableHeader(headerRow);
            this.BuildTableBody();
            TableRow footerRow = new TableRow();
            footerRow.TableSection = TableRowSection.TableFooter;
            this.table.Rows.Add(footerRow);
            this.BuildTableFooter(footerRow);
            if (SelectDayVariant == ServiceDayVariant.SetQuantity) {
                TableRow actionRow = new TableRow();
                actionRow.TableSection = TableRowSection.TableFooter;
                this.table.Rows.Add(actionRow);
                this.BuildTableFooterActionLine(footerRow, actionRow);
            }
        }

        public ServiceForDays() {
            this.SelectDayVariant = ServiceDayVariant.Checkbox;
        }

        private void BuildTableBody() {
            DateTime sd = this.GetCalendarFromDate();
            DateTime ed = this.GetCalendarToDate();

            TableRow row = this.BuildBodyRow();

            BuildActiveCell buildCell = null;
            switch (this.SelectDayVariant) {
                case ServiceDayVariant.SetQuantity:
                    buildCell = BuildActiveCellForSetQuantity;
                    break;
                default:
                    buildCell = BuildActiveCellForCheckbox;
                    break;
            }

            while (sd <= ed) {
                TableCell cell = new TableCell();
                row.Cells.Add(cell);
                if (this.IsActiveDate(sd))
                    buildCell(cell, sd);
                if (sd.DayOfWeek == DayOfWeek.Sunday) {
                    this.table.Rows.Add(row);
                    row = this.BuildBodyRow();
                }
                sd = sd.AddDays(1);
            }

        }

        private delegate void BuildActiveCell(TableCell cell, DateTime date);

        private void BuildActiveCellForCheckbox(TableCell cell, DateTime date) {
            Literal txt = new Literal();
            HyperLink setLink = new HyperLink();
            HyperLink unsetLink = new HyperLink();
            CheckBox checkData = new CheckBox();

            cell.Controls.Add(txt);
            cell.Controls.Add(setLink);
            cell.Controls.Add(unsetLink);
            cell.Controls.Add(checkData);

            txt.Text = date.ToString(CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern.ReplaceEx("MMMM", "MMM"));

            setLink.Text = HttpContext.GetGlobalResourceObject("Aparts","iSelect").ToFirstUpperString();
            setLink.CssClass = "check";

            unsetLink.Text = HttpContext.GetGlobalResourceObject("Aparts", "cancel").ToFirstUpperString();
            unsetLink.CssClass = "uncheck";

            checkData.ID = "SelectedData";
            checkData.InputAttributes.Add("value", date.ToString("dd.MM.yyyy"));
            checkData.Style.Add(HtmlTextWriterStyle.Display, "none");

            this.refCheckbox = checkData;
        }

        private void BuildActiveCellForSetQuantity(TableCell cell, DateTime date) {
            Literal txt = new Literal();
            Label lblFor = new Label();
            TextBox txtQuantity = new TextBox();
            Panel pnlHoldEdit = new Panel();

            cell.Controls.Add(txt);
            cell.Controls.Add(pnlHoldEdit);
            pnlHoldEdit.Controls.Add(lblFor);
            pnlHoldEdit.Controls.Add(txtQuantity);

            txt.Text = date.ToString(CultureInfo.CurrentCulture.DateTimeFormat.LongDatePattern.ReplaceEx("MMMM", "MMM"));

            txtQuantity.ID = "txtQuantity_" + date.ToString("ddMMyyyy");
            txtQuantity.Text = "0";

            lblFor.Text = HttpContext.GetGlobalResourceObject("Aparts", "quanPiece").ToString();
            lblFor.AssociatedControlID = txtQuantity.ID;

            pnlHoldEdit.CssClass = "addserv-hold-quantity";

            this.refBoxes.Add(txtQuantity);
        }

        private bool IsActiveDate(DateTime date) {
            return date >= this.FromDate && date <= this.ToDate;
        }

        private TableRow BuildBodyRow() {
            TableRow row = new TableRow();
            row.TableSection = TableRowSection.TableBody;
            return row;
        }

        private DateTime GetCalendarFromDate() {
            this.FromDate = this.FromDate.Date;
            DateTime sd = this.FromDate;

            while (sd.DayOfWeek != DayOfWeek.Monday)
                sd = sd.AddDays(-1);

            return sd;
        }

        private DateTime GetCalendarToDate() {
            this.ToDate = this.ToDate.Date;
            DateTime ed = this.ToDate;

            while (ed.DayOfWeek != DayOfWeek.Sunday)
                ed = ed.AddDays(1);

            return ed;
        }

        private void BuildTableHeader(TableRow headerRow) {
            headerRow.Cells.Clear();
            DateTime refDate = new DateTime(2001, 1, 1); // poniedziałek
            do {
                TableCell cell = new TableCell();
                headerRow.Cells.Add(cell);
                cell.Text = refDate.ToString("ddd");
                refDate = refDate.AddDays(1);
            }
            while (refDate.DayOfWeek != DayOfWeek.Monday);
        }

        private void BuildTableFooter(TableRow footerRow) {
            int cnt = 7;
            while (cnt > 0) {
                footerRow.Cells.Add(new TableCell());
                cnt--;
            }
        }

        private void BuildTableFooterActionLine(TableRow footerRow, TableRow actionRow) {
            footerRow.Cells[0].CssClass = "checkin-outer";
            footerRow.Cells[0].Controls.Add(new Panel());
            TableCell cell = new TableCell();
            cell.CssClass = "checkin-filler";
            cell.ColumnSpan = 4;
            actionRow.Cells.Add(cell);
            cell = new TableCell();
            cell.CssClass = "checkin-action";
            cell.ColumnSpan = 3;

            Panel pnlWrapper = new Panel();
            cell.Controls.Add(pnlWrapper);

            Panel pnlEditWrap = new Panel();
            pnlWrapper.Controls.Add(pnlEditWrap);

            Label lbl = new Label();
            TextBox txtEdit = new TextBox();
            Panel pnlClear = new Panel();
            pnlEditWrap.Controls.Add(lbl);
            pnlEditWrap.Controls.Add(txtEdit);
            pnlEditWrap.Controls.Add(pnlClear);

            pnlEditWrap.CssClass = "addserv-hold-quantity";
            txtEdit.ID = "txtQuantity_all";
            txtEdit.Text = " - ";
            lbl.Text = HttpContext.GetGlobalResourceObject("Aparts", "equalAmount").ToString();
            lbl.AssociatedControlID = txtEdit.ID;
            pnlClear.CssClass = "clear";

            actionRow.Cells.Add(cell);
        }

        public Dictionary<DateTime, int> GetDayValues() {
            Dictionary<DateTime, int> vv = new Dictionary<DateTime, int>();
            if (SelectDayVariant == ServiceDayVariant.SetQuantity) {
                foreach (TextBox box in this.refBoxes) {
                    DateTime dt = DateTime.MinValue;
                    int v = 0;
                    if (DateTime.TryParseExact(box.ID.ReplaceEx("txtQuantity_", ""), "ddMMyyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt)
                        && Int32.TryParse(Page.Request[box.UniqueID], out v)) {
                        vv.Add(dt, v);
                    }
                }
            }
            else {
                string v = Page.Request[this.refCheckbox.UniqueID];
                if (!String.IsNullOrEmpty(v)) {
                    foreach (string date in v.Split(',')) {
                        DateTime dt = DateTime.MinValue;
                        if (DateTime.TryParseExact(date, "dd.MM.yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out dt))
                            vv.Add(dt, 1);
                    }
                }
            }
            return vv;
        }

        #endregion

    }
}